<template>
  <div ref="canvas"></div>
</template>

<script lang="ts" setup>
import * as THREE from "three";
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import {onMounted, ref} from "vue";

const canvas = ref<any>('')
// 场景 scene
const scene = new THREE.Scene();
// 几何体对象
const geometry = new THREE.BoxGeometry(100, 100, 100);
// 材质对象Material
const material = new THREE.MeshLambertMaterial({
  color: 0x00ffff, // 设置材质颜色
  transparent: true,// 开启透明
  opacity: 0.5,// 设置透明度
});
// Mesh 网格模型
for (let i = 0; i < 10; i++) {
  for (let j = 0; j < 10; j++) {
    const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
    // 在XOZ平面上分布
    mesh.position.set(i * 200, 0, j * 200);
    scene.add(mesh); //网格模型添加到场景中
  }
}
// 辅助观察的坐标点
const axesHelper = new THREE.AxesHelper(1000);
scene.add(axesHelper);
// 光源
const pointLight = new THREE.PointLight(0xffffff, 1.0);
pointLight.position.set(400, 200, 300);
scene.add(pointLight);
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambientLight);

// 相机 - 透视投影相机的投影规律是远小近大，通过相机观察阵列立方体大小变化，可以看到距离相机越远，立方体的渲染视觉效果越小
//       增加相机视角fov，视锥体范围更大，意味着可以看到渲染范围更大，远小近大的视觉效果更明显
// const camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 3000);
const camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 8000);
// camera.position.set(292, 223, 185);
// camera.position.set(500, 500, 500);
// 在原来相机位置基础上拉远，可以观察到更大的范围
camera.position.set(2000, 2000, 2000);
// 相机看向哪个点，即哪个点出现在画布的中心点
// camera.lookAt(0, 0, 0);
camera.lookAt(1000, 0, 1000);

// 创建渲染器对象
const renderer = new THREE.WebGLRenderer();
// 设置three.js渲染区域的尺寸(像素px)
renderer.setSize(window.innerWidth, window.innerHeight);
/**
 * 渲染函数
 */
function render() {
  // 执行渲染操作
  renderer.render(scene, camera);
  requestAnimationFrame(render);
}

// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 相机控件.target属性在OrbitControls.js内部表示相机目标观察点，默认0,0,0
// console.log('controls.target', controls.target);
controls.target.set(1000, 0, 1000);
// update()函数内会执行camera.lookAt(controls.target)
controls.update();

onMounted(() => {
  // 将Canvas画布插入到HTML元素中
  canvas.value.appendChild(renderer.domElement);
  render();
});

</script>
